// @ts-nocheck
import { FC, useContext, useEffect, useRef, useState } from "react";
import { Select, SelectProps, Empty, Spin, Popover } from "antd";

import { getTempData } from "@ey-utils/utils/services/get-temp-data";

import template from "es6-template-strings";
const TEMPLATE_REG_EXP = /\${[0-9.A-Za-z]*}/;

import { useIntl } from "react-intl";
import { DynamicObjectAny } from "@ey-utils/utils/typings";
import { getPathValue } from "@ey-utils/utils/utils";
import { useField, useForm } from "@formily/react";

import { isEqual } from "lodash";

import {
  ExclamationCircleOutlined,
} from '@ant-design/icons';

export interface RemoteSelectProps<V = any>
    extends Omit<SelectProps<any>, "onChange"> {
  valueTemplateKey?: string;
  labelTemplateKey?: string;
  remoteDataPath?: string[];
  filterData?: string[];
  onChange: (value: V, record?: DynamicObjectAny | DynamicObjectAny[]) => void;
  editable?: boolean;
  api?: {
    type: "get" | "post";
    url: string;
    params: DynamicObjectAny;
  };
  initDefaultValue?: boolean;
  data?: any[];
  _value?: string;
  allowClear?: boolean;
  label: string;
  required: boolean;
  title: string,
  content: any,
  iconHidden: boolean
}

const RemoteSelectLabel: FC<RemoteSelectProps> = ({
                                               valueTemplateKey,
                                               labelTemplateKey,
                                               showSearch,
                                               onChange,
                                               value,
                                               editable,
                                               mode,
                                               placeholder,
                                               api,
                                               remoteDataPath,
                                               initDefaultValue,
                                               filterData,
                                               _value,
                                               data,
                                               allowClear = true,
                                               label,
                                               required,
                                               title,
                                               content,
                                               iconHidden,
                                               ...restProps
                                             }) => {
  const { formatMessage } = useIntl();

  const [loading, setLoading] = useState(false);

  const [options, setOptions] = useState<any[]>([]);

  const [dataSource, setDataSource] = useState<any[]>([]);

  const selectRef = useRef<any>(undefined);

  const [limitNum, setLimitNum] = useState(0);

  const [prevApi, setPrevApi] = useState<any>(null);

  let form: any = null;
  try {
    form = useForm();
  } catch (e) {}

  let field: any = null;
  try {
    field = useField();
  } catch (e) {}

  const findRecord = (val: string): undefined | DynamicObjectAny => {
    return val ? dataSource.find((item) => item.value === val) : undefined;
  };

  const triggerChange = (changedValue: any) => {
    const record = Array.isArray(changedValue)
        ? changedValue
            .map((val) => {
              return findRecord(val);
            })
            .filter((val) => val)
        : findRecord(changedValue);

    onChange?.(changedValue, record);

    if (record) {
      if (restProps?.context?.type === "NORMAL" && form && field) {
        // 处理 codeName
        const key = field?.props?.name;
        const labelProp = restProps?.optionLabelProp || "label";
        form.setValuesIn(key + "Name", record[labelProp]);

        // 处理targeyKey
        const targetKey: any[] = restProps?.targetKey || [];
        const targetKeyMap: any = restProps?.targetKeyMap || {};
        targetKey.forEach((k: any) => {
          form.setValuesIn(k, record[targetKeyMap[k] || k]);
        });
      }
    } else {
      if (!changedValue) {
        // 处理targeyKey 清空
        const targetKey: any[] = restProps?.targetKey || [];
        const targetKeyMap: any = restProps?.targetKeyMap || {};
        targetKey.forEach((k: any) => {
          form.setValuesIn(k, "");
        });
      }
    }
  };

  const transformData = (data: any): any[] => {
    return data.map((item: any) => {
      const { name, code } = item;

      const isLabelTemplateString = TEMPLATE_REG_EXP.test(
          labelTemplateKey || ""
      );
      const isValueTemplateString = TEMPLATE_REG_EXP.test(
          valueTemplateKey || ""
      );

      let newLabel = labelTemplateKey ? item[labelTemplateKey] : name;
      let newValue = valueTemplateKey ? item[valueTemplateKey] : code;

      if (isLabelTemplateString) {
        newLabel = template(labelTemplateKey, item);
      }

      if (isValueTemplateString) {
        newValue = template(valueTemplateKey, item);
      }

      return {
        ...item,
        label: newLabel,
        value: newValue,
      };
    });
  };

  /***
   * 模糊匹配
   */
  const search = () => {
    if (!api || !(api && api.url)) {
      return;
    }

    setLoading(true);
    getTempData(api)
        .then((res: any) => {
          setLoading(false);
          const remoteData = getPathValue(res, remoteDataPath);
          const newData = remoteData ? transformData(remoteData) : [];
          setDataSource(newData);
          setOptions(newData);

          setLimitNum((num) => num + 1);

          setPrevApi(api);
        })
        .catch(() => {
          setLoading(false);
        });
  };

  const handleSearch = (likeValue: string) => {
    const caseLikeValue = likeValue?.toLocaleUpperCase() || "";
    const newOptions = likeValue
        ? dataSource.filter((item) => {
          const { value, label } = item;
          return (
              value.toLocaleUpperCase().includes(caseLikeValue) ||
              label.toLocaleUpperCase().includes(caseLikeValue)
          );
        })
        : dataSource;
    setOptions(newOptions);
  };

  const handleFocus = () => {
    if (!dataSource.length) {
      search();
    }
  };

  const handleBlur = () => {
    setOptions(dataSource);
  };

  const handleChange = (value: any) => {
    triggerChange(value);
  };

  useEffect(() => {
    setDataSource([]);
    setOptions([]);
    setLimitNum(0);
  }, [JSON.stringify(api)]);

  useEffect(() => {
    if (!editable) return;

    if (value && !dataSource.length) {
      if (limitNum < 3) {
        search();
      }
    }
  }, [dataSource, value, editable, limitNum]);

  useEffect(() => {
    if (
        initDefaultValue &&
        !value &&
        dataSource.length &&
        isEqual(api, prevApi)
    ) {
      triggerChange(dataSource[0].value);
    }
  }, [initDefaultValue, dataSource, api, prevApi, value]);

  useEffect(() => {
    if (!editable) return;

    if (initDefaultValue && !dataSource.length) {
      if (limitNum < 3) {
        search();
      }
    }
  }, [dataSource, initDefaultValue, limitNum, editable]);

  useEffect(() => {
    if (data) {
      const newData = transformData(data);
      setDataSource(newData);
      setOptions(newData);
      setPrevApi({});
    }
  }, [JSON.stringify(data || [])]);
  
  let title1 = title?title:'加油费说明';
  let content1 = content?content:['无加油费说明'];
  const contentNew = (<div>
  {
    content1.map((item,index)=>{
      return(
        <p key={index}>{ item }</p>
      ) 
    })
  }
  </div>)

  return editable ? (
    <div style={{display:'flex'}}>
      <div class="ant-formily-item-label ant-formily-item-item-col-6" style={{justifyContent: 'flex-end'}}>
        {
          required ? <>
            <span class="ant-formily-item-asterisk">*</span>
          </> : <></>
        }
        <div class="ant-formily-item-label-content">
          <label style={{margin:'0 5px'}}>{label}</label>
          {
            iconHidden?
            <></>:<>
              <Popover content={contentNew} title={title1} zIndex='1000'>
                <ExclamationCircleOutlined />
              </Popover>
            </>
          }
        </div>
        <span class="ant-formily-item-colon">:</span>
      </div>
      <div class="ant-formily-item-control ant-formily-item-item-col-18">
        <div class="ant-formily-item-control-content">
          <div class="ant-formily-item-control-content-component">
          <Select
              value={value}
              {...restProps}
              loading={loading}
              mode={mode}
              style={{ width: "100%" }}
              allowClear={allowClear}
              showSearch={showSearch}
              filterOption={false}
              onSearch={handleSearch}
              onFocus={handleFocus}
              onBlur={handleBlur}
              options={
                filterData?.length
                    ? options.filter((item) => {
                      return !(filterData || []).includes(item.value);
                    })
                    : options
              }
              onChange={handleChange}
              ref={selectRef}
              notFoundContent={
                <Spin spinning={loading}>
                  <Empty />
                </Spin>
              }
              placeholder={
                placeholder
                    ? formatMessage({
                      id: (placeholder as string) || "select.default.placeholder",
                    })
                    : undefined
              }
          />
          </div>
        </div>
      </div>
    </div>
  ) : (
      <span>{_value || value}</span>
  );
};

RemoteSelectLabel.defaultProps = {
  optionLabelProp: "label",
  showSearch: true,
  editable: true,
  valueTemplateKey: "code",
  labelTemplateKey: "name",
};

export default RemoteSelectLabel;
